package com.ljx.funchat.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ljx.funchat.chat.dao.ContactDao;
import com.ljx.funchat.chat.dao.RoomGroupMemberDao;
import com.ljx.funchat.chat.domain.entity.RoomGroupMember;
import com.ljx.funchat.chat.service.adapter.ContactAdapter;
import com.ljx.funchat.chat.service.adapter.RoomAdapter;
import com.ljx.funchat.common.utils.AssertUtil;
import com.ljx.funchat.sensitive.service.SensitiveService;
import com.ljx.funchat.user.dao.UserDao;
import com.ljx.funchat.user.domain.entity.User;
import com.ljx.funchat.user.domain.vo.req.UserBatchReq;
import com.ljx.funchat.user.domain.vo.req.UserInfoUpdateReq;
import com.ljx.funchat.user.domain.vo.resp.UserBatchResp;
import com.ljx.funchat.user.domain.vo.resp.UserResp;
import com.ljx.funchat.user.service.UserService;
import com.ljx.funchat.user.service.cache.UserInfoCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private UserInfoCache userInfoCache;

    @Autowired
    private RoomGroupMemberDao roomGroupMemberDao;

    @Autowired
    private ContactDao contactDao;

    @Autowired
    private SensitiveService sensitiveService;

    @Override
    public Long register(User insert) {
        userDao.save(insert);
        // 保存默认进行入全员群
        RoomGroupMember roomGroupMember = RoomAdapter.buildRoomMemberFirstSave(insert.getId());
        roomGroupMemberDao.save(roomGroupMember);
        // 保存会话
        contactDao.save(ContactAdapter.buildContactFirstSave(insert.getId()));
        return insert.getId();
    }

    @Override
    public List<UserBatchResp> getUserBath(Long uid, UserBatchReq req) {
        Map<Long, Long> modifyTimeMap = req.getUserList().stream()
                .collect(Collectors.toMap(UserBatchReq.UserInfoReq::getUid,
                        user -> Optional.ofNullable(user.getLastModifyTime()).orElse(-1L))); // 无最新时间就用-1标识
        List<Long> uIds = req.getUserList().stream().map(UserBatchReq.UserInfoReq::getUid).collect(Collectors.toList());
        Map<Long, User> userMap = userInfoCache.getBatch(uIds);
        return userMap.values().stream().map(item -> {
            boolean isNeedFresh = isNeedFresh(modifyTimeMap.get(item.getId()), item.getUpdateTime());
            if (!isNeedFresh) {
                return UserBatchResp.skip(item.getId());
            }
            UserBatchResp userBatchResp = new UserBatchResp();
            userBatchResp.setUid(item.getId());
            userBatchResp.setName(item.getName());
            userBatchResp.setAvatar(item.getAvatar());
            return userBatchResp;
        }).collect(Collectors.toList());
    }

    private boolean isNeedFresh(Long before, Date now) {
        return Objects.isNull(before) || (Objects.nonNull(now) && now.getTime() > before);
    }

    @Override
    public UserResp getUserInfo(Long uid) {
        User user = userInfoCache.get(uid);
        return BeanUtil.copyProperties(user, UserResp.class);
    }

    @Override
    public void updateUserInfo(Long uid, UserInfoUpdateReq req) {
        // 判断是否是敏感词
        AssertUtil.equal(sensitiveService.getFilterStr(req.getName()), "***", "名字中包含敏感词，请重新输入");
        // 判断是否重复
        Integer count = userDao.countByName(req.getName());
        AssertUtil.equal(count, 1, "名字已经被抢占了，请换一个");
        userDao.updateUserInfo(uid, req);
        // 删除缓存
        userInfoCache.delete(uid);
    }
}
